<?php
namespace App\Logic;


use App\Http\Logic\MachineLogic;
use App\Http\Logic\OrderLogic;
use App\Http\Logic\PayLogic;
use App\Jobs\NoticeUser;
use App\Jobs\RecognitionVideo;
use App\Models\SwtBjCabinet;
use App\Models\SwtBjMachine;
use App\Models\SwtBjOpen;
use App\Models\SwtOrder;
use App\Services\BaoJianService;
use App\Services\TuoYuanService;
use Illuminate\Support\Facades\Cache;

class BaoJianMachineLogic extends BaseLogic {

    /**
     * @notes 获取宝坚设备门是否可以开启
     * @param $device_code
     * @return boolean
     * @throws \Illuminate\Http\Client\RequestException
     * @author Evil丿
     * @date 2024/08/30 12:08
     */
    public static function getDoorStatus($device_code)
    {
        $info = BaoJianService::machineStatus($device_code);

        if($info['powerStatus'] == 2 || $info['netStatus'] == 2 || $info['saleStatus'] == 2) {
            self::$error = "设备停售";
            return false;
        }

        return true;
    }

    public static function openDoor($order_info)
    {
        $device_code = SwtBjMachine::where('machine_id', $order_info['machine']['id']) ->value('device_code');

        $res = BaoJianService::openDoor($device_code, $order_info['door_num'], 1);

        if($res) {
            self::setOpenEvent($order_info, $device_code,1, $res);
        }

        return $res;
    }

    /**
     * @notes 新增设备开门记录
     * @param $order_info
     * @param $device_code
     * @param $event_type
     * @param $params
     * @return bool
     * @author Evil丿
     * @date 2024/09/26 16:08
     */
    public static function setOpenEvent($order_info, $device_code, $event_type, $params)
    {
        $data = [
            'order_id'    => $order_info['id'],
            'machine_id'  => $order_info['machine_id'],
            'event_id'    => $params['eventId'],
            'event_type'  => $event_type,
            'device_code' => $device_code,
            'cabinet_no'  => $order_info['door_num'],
            'open_sn'     => $params['outOpenNo']
        ];

        $res = SwtBjOpen::create($data);

        if(!$res) {
            self::$error = "开锁记录新增失败";
            return false;
        }

        return true;
    }

    /**
     * @notes 修改设备状态
     * @param $params
     * @return bool
     * @author Evil丿
     * @date 2024/09/26 14:54
     */

    public static function updateMachineStatus($params)
    {
        $machine = SwtBjMachine::firstWhere('device_code', $params['deviceCode']);

        if(!$machine) {
            self::$error = "宝坚设备未找到";
            return false;
        }

        $machine -> power_status = $params['powerStatus'];
        $machine -> online_status = $params['netStatus'];
        $machine -> sale_status = $params['saleStatus'];

        $machine -> save();

        foreach($params['cabinetList'] as $v) {
            SwtBjCabinet::where('bj_machine_id', $machine -> id)->where('cabinet_no', $v['cabinetNo'])->update(['lock_status' => $v['lockStatus']]);
        }

        return true;
    }

    /**
     * @notes 修改开门视频
     * @param $params
     * @return true
     * @author Evil丿
     * @date 2024/12/12 14:52
     */
    public static function updateOpenEventVideo($params)
    {
        $info = SwtBjOpen::with(['order','replenish']) -> firstWhere('event_id', $params['eventId']);

        if($info -> order) {
            self::buyOpenEvent($info, $params);
        }

        if($info -> replenish) {
            self::replenishOpenEvent($info, $params);
        }

        return true;
    }

    /**
     * @notes 开门购物事件
     * @param $open_info
     * @param $params
     * @return true
     * @throws \Illuminate\Http\Client\RequestException
     * @author Evil丿
     * @date 2024/12/31 09:48
     */
    public static function buyOpenEvent($open_info, $params)
    {
        $order_info = $open_info -> order;
        switch($params['resultCode'])
        {
            case 'FAIL' :
                NoticeUser::dispatch($order_info -> id, 3, '设备视频上传失败')->onQueue('notice_user');
                OrderLogic::setWarningOrder($order_info -> order_sn, $order_info -> door_num,'设备上传视频失败');
                break;
            case 'UNOPENED' :
                OrderLogic::cancelOrder($order_info -> order_sn, $order_info -> door_num, $order_info -> platform);
                break;
            case 'SUCCESS' :
                if (count($params['videoList']) < 2) {
                    BaoJianService::uploadVideo($params['eventId']);
                } else {
                    foreach ($params['videoList'] as $v) {
                        if ($v['cameraNo'] == 1) {
                            $open_info->video_main_url = $v['videoUrl'];
                        } else {
                            $open_info->video_auxiliary_url = $v['videoUrl'];
                        }
                    }
                    $open_info->open_status = 1;
                    $open_info->lock_status = 2;
                    $open_info->open_time   = $open_info->open_time ?: time();
                    $open_info->close_time  = time();
                    $open_info->save();
                    RecognitionVideo::dispatch($order_info->id)->onQueue('recognition_video');
                }
        }
        return true;
    }

    /**
     * @notes 补货开锁
     * @param $open_info
     * @param $params
     * @return true
     * @author Evil丿
     * @date 2024/12/31 09:55
     */
    public static function replenishOpenEvent($open_info, $params)
    {
    }

    /**
     * @notes 修改开门记录
     * @param $params
     * @return bool
     * @author Evil丿
     * @date 2024/12/12 14:51
     */
    public static function updateOpenEvent($params)
    {
        $info = SwtBjOpen::with('order')->firstWhere('event_id', $params['eventId']);

        $order_info = $info -> order;

        $res = Cache::has('open_machine_' . $info['device_code'] . '_' . $info['cabinet_no']);

        if($res) {
            Cache::forget('open_machine_'. $info['device_code'] . '_' . $info['cabinet_no']);
        }

        if($params['resultCode'] == 'FAIL') { //开锁失败则取消订单
            $info -> open_status = 2;
            $info -> failed_msg = $params['resultMsg'];

            //存在订单则取消
            if( $order_info ) {
                //事件为录制视频的时候报警
                if( $info -> event_type == 1) {
                    NoticeUser::dispatch($order_info -> id, 1, '开锁失败:'.$params['resultMsg'])->onQueue('notice_user');
                }
                OrderLogic::cancelOrder($order_info -> order_sn, $order_info -> door_num, $order_info -> platform);
            }
        } else {
            switch ($params['type']) {
                case 'OPEN' : //门已开
                    $info -> open_status = 1;
                    $info -> lock_status = 1;
                    $info -> open_time = time();
                    break;
                case "CLOSE": //门已关
                    $info -> open_status = 1;
                    $info -> lock_status = 2;
                    $info -> open_time = $info -> open_time ? : time();
                    $info -> close_time = time();
                    //释放门锁状态
                    if( $order_info ) {
                        MachineLogic::clearMachineCacheLock($order_info -> order_sn, $order_info -> door_num);
                    }
                    break;
            }
        }

        $res = $info -> save();

        if(!$res) {
            self::$error = "开锁记录更新失败";
            return false;
        }

        return true;
    }

    /**
     * @notes 重新完结订单
     * @param $order_sn
     * @return bool
     * @author Evil丿
     * @date 2025/01/08 17:17
     */
    public static function finishRecognitionOrder($order_sn)
    {

        $info = SwtOrder::firstWhere('order_sn', $order_sn);

        if(!$info) {
            self::$error = "订单不存在";
            return false;
        }

        $params = TuoYuanService::getVideoInfo($order_sn);

        $result = $params['data'];

        if($result['status'] !== 20000) {
            OrderLogic::setWarningOrder($info->order_sn, $info->door_num, $result['status'].'-'.$result['errmsg']);

            NoticeUser::dispatch($info -> id, 3, $result['status'].'-'.$result['errmsg'])->onQueue('notice_user');

            self::$error = $result['status'].'-'.$result['errmsg'];
            return false;
        }

        $goods = $result['result'];

        $amount = 0;

        $order_goods = [];

        foreach($goods as $good) {
            $price = (int) bcmul($good['price'],100);

            $amount += $price * $good['number'];

            $order_goods[] = [
                "barcode"  => $good['skuId'],
                "name"     => $good['skuName'],
                "quantity" => $good['number'],
                "amount"   => $price * $good['number']
            ];
        }

        $res = PayLogic::goPay($info -> toArray(), $amount, $order_goods);

        if($res === false) {
            self::$error = PayLogic::getErrorMessage();
            return false;
        }

        $info -> video_status = 2;

        $info -> save();

        return true;
    }
}
